﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ServiceModel;
using CommunicationDataContract;
using System.Windows.Threading;
using System.Threading;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace CommunicationDesktopApplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private enum ServiceStateType
        {
            Stoped,
            Paused,
            Started
        }

        public TimeSpan NextCheckIn = new TimeSpan(0,0,0);
        public MainWindow()
        {
            InitializeComponent();
            lblAppGuid.Content = DesktopServiceController.Instance.ApplicationId.ToString();
            DesktopServiceController.Instance.PropertyChanged += new PropertyChangedEventHandler(DesktopServiceController_Instance_PropertyChanged);
            StartSeriveEndPoint();
            PollingWorkerThread();
            var pingColor = Color.FromRgb(DesktopServiceController.Instance.ApplicationColor[0], DesktopServiceController.Instance.ApplicationColor[1], DesktopServiceController.Instance.ApplicationColor[2]);
            rglColor.Fill = new SolidColorBrush(pingColor);
        }

      

        protected void DesktopServiceController_Instance_PropertyChanged(object sender, PropertyChangedEventArgs obj)
        {
            if (obj.PropertyName == "IsWindowsServiceActive")
            {
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { CheckServiceForUpdate(); }));
            }
            else if (obj.PropertyName == "ApplicationIdLastPing")
            {
                ApplicationInfo appInfo;
                using (var desktopConnection = new DesktopApplicationConnection(DesktopServiceController.Instance, DesktopServiceController.Instance.ApplicationIdLastPing))
                {
                    appInfo = desktopConnection.GetApplicationInfo();
                }
                Color pingColor = default(Color);

                if (appInfo != null)
                    pingColor = Color.FromRgb(appInfo.ColorBytes[0], appInfo.ColorBytes[1], appInfo.ColorBytes[2]);

                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => {
                    lblAppPingGuid.Content = DesktopServiceController.Instance.ApplicationIdLastPing;
                    if (pingColor != default(Color))
                    {
                        lblAppPingGuid.Background = new SolidColorBrush(pingColor);
                    }
                }));
            }
        }

        private void CheckServiceForUpdate()
        {
            try
            {
                using (var windowsServiceConnection = new WindowsServiceApplicationConnection(DesktopServiceController.Instance))
                {
                    if (!windowsServiceConnection.IsWindowsServiceRunning())
                    {
                        this.Background = Brushes.Orange;
                        lblServiceStatus.Text = "Service not running!";
                        lblJobStatus.Text = "Job Cannot Run";

                        btnPauseJob.IsEnabled = false;
                        btnStartJob.IsEnabled = false;
                        btnDisableService.IsEnabled = false;
                        btnEnableService.IsEnabled = true;
                    }
                    else
                    {
                        if (windowsServiceConnection.IsJobRunning())
                        {
                            this.Background = Brushes.Green;
                            lblServiceStatus.Text = "Service Running";
                            lblJobStatus.Text = "Job Running";

                            btnPauseJob.IsEnabled = true;
                            btnStartJob.IsEnabled = false;
                            btnDisableService.IsEnabled = true;
                            btnEnableService.IsEnabled = false;
                        }
                        else
                        {
                            this.Background = Brushes.Yellow;
                            lblServiceStatus.Text = "Service Running";
                            lblJobStatus.Text = "Job Paused";

                            btnPauseJob.IsEnabled = false;
                            btnStartJob.IsEnabled = true;
                            btnDisableService.IsEnabled = true;
                            btnEnableService.IsEnabled = false;
                        }
                        
                    }
                }
            }
            catch (Exception ex)
            {
                this.Background = Brushes.Red;

                lblServiceStatus.Text = "Service Error!";
                lblJobStatus.Text = "Job Cannot Run";

                btnPauseJob.IsEnabled = false;
                btnStartJob.IsEnabled = false;
                btnDisableService.IsEnabled = false;
                btnEnableService.IsEnabled = true;
            }
        }
       
        private void PollingWorkerThread()
        {
            new Thread(() =>
            {
                var waitTime = new TimeSpan(0,0,1);
                Thread.Sleep(waitTime);
                if (NextCheckIn.Seconds <= 0)
                    NextCheckIn = new TimeSpan(0, 0, 10);
                else
                    NextCheckIn = NextCheckIn.Subtract(waitTime);

                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => 
                {
                    lblNextUpdateValue.Content = NextCheckIn.Seconds;
                    if (NextCheckIn.Seconds == 10)
                    {
                        CheckServiceForUpdate();
                    }
                    else
                    {
                        using (var windowsServiceConnection = new WindowsServiceApplicationConnection(DesktopServiceController.Instance))
                        {
                            if (windowsServiceConnection.IsWindowsServiceRunning())
                                DesktopApplicationConnection.UpdateAttachedApplications(DesktopServiceController.Instance, windowsServiceConnection.GetAttachedApplicationIds());
                        }
                    }
                    PollingWorkerThread();
                }));
            }).Start();
        }

        private void Window_Unloaded(object sender, RoutedEventArgs e)
        {
            StopSeriveEndPoint();
        }


        private void btnDisableService_Click(object sender, RoutedEventArgs e)
        {
            btnEnableService.IsEnabled = false;
            btnDisableService.IsEnabled = false;
            new Thread(() =>
            {
                using (var windowsServiceConnection = new WindowsServiceApplicationConnection(DesktopServiceController.Instance))
                {
                    windowsServiceConnection.WindowsServiceStop();
                }
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    btnEnableService.IsEnabled = true;
                }));
            }).Start();
        }

        private void btnEnableService_Click(object sender, RoutedEventArgs e)
        {
            btnEnableService.IsEnabled = false;
            btnDisableService.IsEnabled = false;
            new Thread(() =>
            {
                using (var windowsServiceConnection = new WindowsServiceApplicationConnection(DesktopServiceController.Instance))
                {
                    windowsServiceConnection.WindowsServiceStart();
                    Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => {CheckServiceForUpdate();}));
                }
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    btnDisableService.IsEnabled = true;
                }));
            }).Start();
          
        }

        private void btnEnableHost_Click(object sender, RoutedEventArgs e)
        {
            StartSeriveEndPoint();
        }

        private void btnDisableHost_Click(object sender, RoutedEventArgs e)
        {
            StopSeriveEndPoint();
        }

        private void btnStartJob_Click(object sender, RoutedEventArgs e)
        {
            btnStartJob.IsEnabled = false;
            new Thread(() =>
            {
                using (var windowsServiceConnection = new WindowsServiceApplicationConnection(DesktopServiceController.Instance))
                {
                    windowsServiceConnection.JobStart();
                }
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    btnPauseJob.IsEnabled = true;
                }));
            }).Start();
        }

        private void btnPauseJob_Click(object sender, RoutedEventArgs e)
        {
            btnPauseJob.IsEnabled = false;
            new Thread(() =>
            {
                using (var windowsServiceConnection = new WindowsServiceApplicationConnection(DesktopServiceController.Instance))
                {
                    windowsServiceConnection.JobPause();
                }
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    btnStartJob.IsEnabled = true;
                }));
            }).Start();
        }

        private void StartSeriveEndPoint()
        {
            btnEnableHost.IsEnabled = false;
            new Thread(() =>
            {
                DesktopServiceController.Instance.ListeningStart();
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    lblHostedService.Text = "Inbound service is on";
                    btnDisableHost.IsEnabled = true;
                }));
            }).Start();
        }
        private void StopSeriveEndPoint()
        {
            btnDisableHost.IsEnabled = false;
            new Thread(() =>
            {
                DesktopServiceController.Instance.ListeningStop();
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    lblHostedService.Text = "Inbound service is off";
                    btnEnableHost.IsEnabled = true;
                }));
            }).Start();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void btnPing_Click(object sender, RoutedEventArgs e)
        {
            //e.Source
            var pingSucceeded = false;
            var item = (Button)sender;
            item.IsEnabled = false;
            var itemData = item.DataContext as ApplicationInfo; 
            item.IsEnabled = false;
            if (itemData.ApplicationId != DesktopServiceController.Instance.ApplicationId)
            {
                new Thread(new ThreadStart(() =>
                {
                    using (var applicationConnection = new DesktopApplicationConnection(DesktopServiceController.Instance, itemData.ApplicationId))
                    {
                        pingSucceeded = applicationConnection.Ping();
                        Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                        {
                            if (pingSucceeded)
                                item.BorderBrush = Brushes.Green;
                            else
                                item.BorderBrush = Brushes.Red;
                            item.IsEnabled = true;
                        }));
                    }
                })).Start();
            }
        }
    }
}
